<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>美食点评 - 预签名URL上传演示</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
      margin: 20px;
      background-color: #f4f4f9;
      color: #333;
    }
    .container {
      max-width: 600px;
      margin: 20px auto;
      padding: 25px;
      background-color: #fff;
      border-radius: 8px;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    }
    .form-group {
      margin-bottom: 18px;
    }
    label {
      display: block;
      margin-bottom: 6px;
      font-weight: bold;
      color: #555;
    }
    input[type="text"],
    input[type="number"],
    textarea,
    input[type="file"] {
      width: 100%;
      padding: 10px;
      border: 1px solid #ccc;
      border-radius: 4px;
      box-sizing: border-box; /* Important for consistent sizing */
      font-size: 1rem;
    }
    textarea {
      resize: vertical; /* Allow vertical resizing */
      min-height: 80px;
    }
    input[type="file"] {
        padding: 5px; /* Adjust padding for file input */
    }
    button {
      display: inline-block;
      padding: 12px 20px;
      background-color: #007bff; /* Blue */
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 1rem;
      transition: background-color 0.3s ease;
    }
    button:hover {
      background-color: #0056b3; /* Darker blue */
    }
    button:disabled {
        background-color: #cccccc;
        cursor: not-allowed;
    }
    .status {
      margin-top: 20px;
      padding: 12px;
      border-radius: 4px;
      font-size: 0.95rem;
    }
    .status.info {
        background-color: #e2f3ff; /* Light blue for info */
        color: #004085;
        border: 1px solid #b8daff;
    }
     .status.success {
        background-color: #d4edda; /* Light green for success */
        color: #155724;
        border: 1px solid #c3e6cb;
    }
    .status.error {
        background-color: #f8d7da; /* Light red for error */
        color: #721c24;
        border: 1px solid #f5c6cb;
    }
    /* Basic responsive adjustments */
    @media (max-width: 600px) {
        .container {
            margin: 10px;
            padding: 15px;
        }
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>📝 美食点评 - 预签名URL上传模式</h1>

    <div class="form-group">
      <label for="userId">学号：</label>
      <input type="text" id="userId" placeholder="请输入你的学号" required>
    </div>

    <div class="form-group">
      <label for="userName">姓名/昵称：</label>
      <input type="text" id="userName" placeholder="（选填）">
    </div>

    <div class="form-group">
      <label for="restaurantName">餐厅名称：</label>
      <input type="text" id="restaurantName" placeholder="例如：东区均园食堂二楼" required>
    </div>

    <div class="form-group">
      <label for="restaurantLocation">餐厅位置：</label>
      <input type="text" id="restaurantLocation" placeholder="例如：靠近图书馆" required>
    </div>

    <div class="form-group">
      <label for="dishName">推荐菜品：</label>
      <input type="text" id="dishName" placeholder="（选填）例如：麻辣香锅">
    </div>

    <div class="form-group">
      <label for="rating">评分 (1-5)：</label>
      <input type="number" id="rating" min="1" max="5" placeholder="输入1到5的整数" required>
    </div>

    <div class="form-group">
      <label for="reviewText">评价内容：</label>
      <textarea id="reviewText" rows="4" placeholder="分享你的美食体验..." required></textarea>
    </div>

    <div class="form-group">
      <label for="images">上传图片：</label>
      <input type="file" id="images" multiple accept="image/jpeg, image/png, image/gif">
    </div>

    <button id="submitBtn">🚀 提交评价</button>

    <div class="status" id="status">请填写信息并提交</div>
  </div>

  <script>
    const submitBtn = document.getElementById('submitBtn');
    const statusElement = document.getElementById('status');
    const fileInput = document.getElementById('images');

    // --- 配置 ---
    //  重要：确保这个地址与你后端 API 运行的地址一致 
    const API_BASE_URL = 'http://localhost:3000';
    // -------------

    function updateStatus(message, type = 'info') {
        statusElement.textContent = message;
        statusElement.className = `status ${type}`; // Reset classes and add new type
        console.log(`[${type.toUpperCase()}] ${message}`);
    }

    submitBtn.addEventListener('click', async function() {
      // 禁用按钮防止重复提交
      submitBtn.disabled = true;
      updateStatus('⏳ 正在处理，请稍候...', 'info');

      try {
        // 1. 收集表单数据
        const userId = document.getElementById('userId').value.trim();
        const userName = document.getElementById('userName').value.trim();
        const restaurantName = document.getElementById('restaurantName').value.trim();
        const restaurantLocation = document.getElementById('restaurantLocation').value.trim();
        const dishName = document.getElementById('dishName').value.trim();
        const rating = document.getElementById('rating').value;
        const reviewText = document.getElementById('reviewText').value.trim();

        // 2. 验证必填字段
        if (!userId || !restaurantName || !restaurantLocation || !rating || !reviewText) {
          updateStatus('⚠️ 请填写所有必填字段 (学号, 餐厅名, 位置, 评分, 内容)', 'error');
          submitBtn.disabled = false; // 重新启用按钮
          return;
        }
        const ratingInt = parseInt(rating);
        if (isNaN(ratingInt) || ratingInt < 1 || ratingInt > 5) {
             updateStatus('⚠️ 评分必须是 1 到 5 之间的整数', 'error');
             submitBtn.disabled = false;
             return;
        }


        // 3. 上传图片（如果有选择）
        const uploadedImageKeys = [];
        const files = fileInput.files;

        if (files.length > 0) {
          updateStatus(`⏳ 准备上传 ${files.length} 张图片...`, 'info');
          for (let i = 0; i < files.length; i++) {
            const file = files[i];
            const fileNumber = i + 1;
            updateStatus(`[${fileNumber}/${files.length}] 正在获取图片 "${file.name}" 的上传授权...`, 'info');

            // 获取预签名URL
            const urlEndpoint = `${API_BASE_URL}/api/upload-url?filename=${encodeURIComponent(file.name)}&contentType=${encodeURIComponent(file.type)}`;
            let urlResponse;
            try {
                 urlResponse = await fetch(urlEndpoint);
            } catch (networkError) {
                 console.error("Network error fetching upload URL:", networkError);
                 throw new Error(`网络错误：无法连接到 API (${urlEndpoint}) 获取上传授权`);
            }


            if (!urlResponse.ok) {
              const errorData = await urlResponse.json().catch(() => ({ error: '无法解析错误信息' }));
              console.error('获取预签名URL失败:', urlResponse.status, errorData);
              throw new Error(`获取上传授权失败 (${urlResponse.status}): ${errorData.error || '未知错误'}`);
            }

            const urlData = await urlResponse.json();

            updateStatus(`[${fileNumber}/${files.length}] 正在上传图片 "${file.name}"...`, 'info');

            // 使用预签名URL上传图片
            let uploadResponse;
            try {
                 uploadResponse = await fetch(urlData.uploadUrl, {
                   method: 'PUT',
                   headers: {
                     'Content-Type': file.type
                   },
                   body: file
                 });
            } catch(networkError) {
                 console.error("Network error uploading to OSS:", networkError);
                 throw new Error(`网络错误：上传图片 "${file.name}" 到 OSS 失败`);
            }


            if (!uploadResponse.ok) {
              // OSS PUT 请求成功通常返回 200 OK，没有响应体。失败时可能有 XML 响应体。
              const errorText = await uploadResponse.text().catch(() => '无法读取OSS错误响应');
              console.error('上传图片到OSS失败:', uploadResponse.status, uploadResponse.statusText, errorText);
              throw new Error(`上传图片 "${file.name}" 失败 (${uploadResponse.status})`);
            }

            // 保存 fileKey 用于后续创建评价
            uploadedImageKeys.push(urlData.fileKey);
            updateStatus(`[${fileNumber}/${files.length}] 图片 "${file.name}" 上传成功!`, 'info');
          }
           updateStatus(`✅ 所有 ${files.length} 张图片上传完成!`, 'info');
        } else {
             updateStatus('ℹ️ 未选择图片。', 'info');
        }

        // 4. 提交评价数据
        updateStatus('⏳ 正在提交评价信息...', 'info');
        const reviewEndpoint = `${API_BASE_URL}/api/reviews`;
        let reviewResponse;
        try {
             reviewResponse = await fetch(reviewEndpoint, {
               method: 'POST',
               headers: {
                 'Content-Type': 'application/json'
               },
               body: JSON.stringify({
                 userId,
                 userName: userName || null, // 如果为空则发送 null
                 restaurantName,
                 restaurantLocation,
                 dishName: dishName || null, // 如果为空则发送 null
                 rating: ratingInt,
                 reviewText,
                 imageKeys: uploadedImageKeys // 发送收集到的 keys
               })
             });
        } catch (networkError) {
             console.error("Network error submitting review:", networkError);
             throw new Error(`网络错误：无法连接到 API (${reviewEndpoint}) 提交评价`);
        }


        const reviewData = await reviewResponse.json(); // 尝试解析 JSON 响应

        if (!reviewResponse.ok) {
          console.error('提交评价失败:', reviewResponse.status, reviewData);
          throw new Error(`提交评价失败 (${reviewResponse.status}): ${reviewData.error || '未知错误'}`);
        }

        updateStatus(`🎉 评价提交成功！评价ID: ${reviewData.id}. ${reviewData.message || ''}`, 'success');
        // 可选：清空表单
        // document.getElementById('userId').value = '';
        // ... reset other fields ...
        fileInput.value = ''; // 清空文件选择

      } catch (error) {
        console.error('💥 操作过程中发生错误:', error);
        updateStatus(`❌ 操作失败: ${error.message}`, 'error');
      } finally {
        // 无论成功或失败，最后都重新启用按钮
        submitBtn.disabled = false;
      }
    });
  </script>
</body>
</html>

